﻿// 1. 对图片进行分类
// 2. 生成dom元素
// 3. 绑定事件
// 4. 显示到页面上
(function(window,document){
	let canChange=true;
	let curPreviewImgindex=0;
	let Img=function(options){
		this._init(options);
		this._createElement();
		this._bind();
		this._show();
	};
	//公共方法
	const methods={
		appendChild(parent,...children){
			children.forEach(function(el){
				parent.appendChild(el);
			})
		},
		$(selector,root=document){
			return root.querySelector(selector);
		},
		$$(selector,root=document){
			return root.querySelectorAll(selector);
		}
	};
	/*初始化
	*data        图片数据
	*initType    初始状态图片显示类型
	*parasitifer 容器，最终挂载到的元素
	*/
	Img.prototype._init=function({data,initType,parasitifer}){
		this.types=['全部'];           	//全部分类
		this.all=[];			      	//全部图片元素
		this.classified={'全部':[]};	   	//已分类图片
		this.curType=initType;			//当前显示的类别，初始状态为initType
		this.parasitifer=methods.$(parasitifer); 		//挂载点，
		this.imgContainer=null;			//所有图片容器
		this.warp=null;					//整体容器
		this.typeBtnEls=null;			//分类按钮组成的数组
		this.figures=null;				//当前显示的图片组成的数组
		this._classify(data);			//分类
		console.log(this.all);
		console.log(this.classified);
	};
	//图片分类
	Img.prototype._classify=function(data){
		let srcs=[];
		data.forEach(({type,title,alt,src})=>{
			if(!this.types.includes(type)){
				this.types.push(type);
			}
			if(!Object.keys(this.classified).includes(type)){
				this.classified[type]=[];
			}

			if (!srcs.includes(src)) {
				//没生成过的新图片
				//生成图片
				//添加到对应的分类中
				srcs.push(src);
				let figure=document.createElement('figure');
				let img=document.createElement('img');
				let figcaption=document.createElement('figcaption');
				img.src=src;
				img.setAttribute('alt',alt);
				figcaption.innerText=title;
				methods.appendChild(figure,img,figcaption);

				this.all.push(figure);
				this.classified[type].push(this.all.length-1);


			}else{
				//生成过的图片
				//找到src或者all中的对应图片
				//添加到对应的分类中

				this.classified[type].push(srcs.findIndex(function(s1){
					if (s1===src) {
						return s1;
					}
				}));

			}
		});

	};
	//根据分类获取图片
	Img.prototype._getImgsByType=function(type){
		return type==='全部'?[...this.all]:this.classified[type].map((index)=>{
			return this.all[index];
		});
	};
	//生成DOM
	Img.prototype._createElement=function(){
		//创建分类按钮
		let typesBtn=[];
		for (let type of this.types) {
			typesBtn.push(`<li class="__Img__classify__type-btn${this.curType===type?' __Img__type-btn-active':''}">${type}</li>`);
		}
		console.log(typesBtn);
		//整体模板
		let template=`<ul class="__Img__classify">
					 ${typesBtn.join('')}
 					 </ul>
 					 <div class="__Img__img-container"></div>`;
 		let warp=document.createElement('div');
 		warp.className='__Img__container';
 		warp.innerHTML=template;	
 		this.imgContainer=methods.$('.__Img__img-container',warp);

 		//插入图片
 		methods.appendChild(this.imgContainer,...this._getImgsByType(this.curType));
 		this.warp=warp;
 		this.typeBtnEls=[...methods.$$('.__Img__classify__type-btn',warp)];
 		this.figures=[...methods.$$('figure',warp)];

 		//遮罩层
 		let overlay=document.createElement('div');
 		overlay.className="__Img__overlay";
 		overlay.innerHTML=`<div class="__Img__overlay-prev-btn"></div>
    					   <div class="__Img__overlay-next-btn"></div>
    					   <img src="" alt="">`;
    	methods.appendChild(warp,overlay);
    	this.overlay=overlay;
    	this.previewImg=methods.$('img',overlay);


    	//调用图片位置计算
    	this._calcPosition(this.figures);
	};

	//从两个数组中取相同元素
	Img.prototype._diff=function(prevImgs,nextImgs){
		let diffArr=[];
		prevImgs.forEach((srcPrev,indexPrev)=>{
			let indexNext=nextImgs.findIndex(srcNext=>srcNext===srcPrev);
			if (indexNext!=-1) {
				diffArr.push([indexPrev,indexNext]);
			}
		});
		return diffArr;
	}
	//绑定事件
	Img.prototype._bind=function(){
		methods.$('.__Img__classify',this.warp).addEventListener('click',({target})=>{
			console.log(target.nodeName);
			if (target.nodeName!='LI') return;
			if (!canChange) return;
			canChange=false;
			const type=target.innerText;
			const els=this._getImgsByType(type);	//下轮显示图片
			let prevImgs=this.figures.map(figure=>methods.$('img',figure).src);
			let nextImgs=els.map(figure=>methods.$('img',figure).src);

			const diffArr=this._diff(prevImgs,nextImgs);

			diffArr.forEach(([,indexNext])=>{
				this.figures.every((figure,index)=>{
					let src=methods.$('img',figure).src;
					if (src===nextImgs[indexNext]) {
						this.figures.splice(index,1);
						return false;
					}
					return true;
				})
			});

			this._calcPosition(els);
			//TODO
			let needAppendEls=[];
			if (diffArr.length) {
				let nextElsIndex=diffArr.map(([,indexNext])=>indexNext);
				els.forEach((figure,index)=>{
					if (!nextElsIndex.includes(index)) {
						needAppendEls.push(figure);
					}
				});
			}else{
				needAppendEls=els;
			}

			this.figures.forEach(el=>{
				el.style.transform='scale(0,0) translate(0,100%)';
				el.style.opacity='0';
			});

			setTimeout(()=>{
				this.figures.forEach(figure=>{
					this.imgContainer.removeChild(figure);
				});
				this.figures=els;
				canChange=true;
			},600);

			methods.appendChild(this.imgContainer,...needAppendEls);

			setTimeout(()=>{
				els.forEach(el=>{
					el.style.transform='scale(1,1) translate(0,0)';
					el.style.opacity='1';
				});
			});

			this.typeBtnEls.forEach(btn=>(
				btn.className='__Img__classify__type-btn'
			));
			target.className='__Img__classify__type-btn __Img__type-btn-active';
		});

		this.imgContainer.addEventListener('click',({target})=>{
			if (target.nodeName!='FIGURE'&&target.nodeName!='FIGCAPTION') return;
			if (target.nodeName==='FIGCAPTION') target=target.parentNode;
			const src=methods.$('img',target).src;
			curPreviewImgindex=this.figures.findIndex(figure=>src===methods.$('img',figure).src);
			this.previewImg.src=src;
			this.overlay.style.display='flex';
			setTimeout(()=>{
				this.overlay.style.opacity='1';
			});

		});

		methods.$('.__Img__overlay-prev-btn',this.overlay).addEventListener('click',(e)=>{
			e.stopPropagation();
			curPreviewImgindex=curPreviewImgindex===0?this.figures.length-1:curPreviewImgindex-1;
			this.previewImg.src=methods.$('img',this.figures[curPreviewImgindex]).src;
		});
		methods.$('.__Img__overlay-next-btn',this.overlay).addEventListener('click',(e)=>{
			e.stopPropagation();
			curPreviewImgindex=curPreviewImgindex===this.figures.length-1?0:curPreviewImgindex+1;
			this.previewImg.src=methods.$('img',this.figures[curPreviewImgindex]).src;
		});

		this.overlay.addEventListener('click',()=>{
			this.overlay.style.opacity='0';
			setTimeout(()=>{
				this.overlay.style.display='none';
			});
		});

	};
	//显示元素
	Img.prototype._show=function(){
		methods.appendChild(this.parasitifer,this.warp);
		setTimeout(()=>{
			this.figures.forEach(figure=>{
				figure.style.transform='scale(1,1) translate(0,0)';
				figure.style.opacity='1';
			});
		});
		
	};

	//计算图片top和left
	Img.prototype._calcPosition=function(figures){
		let horizontalImgIndex=0;//参考线，每一行的第几张图，0~3
		figures.forEach((figure,index)=>{
			figure.style.top=parseInt(index/4)*(140+15)+'px';
			figure.style.left=horizontalImgIndex*(240+15)+'px';
			figure.style.transform='scale(0,0) translate(0,-100%)'
			horizontalImgIndex=(horizontalImgIndex+1)%4;
		});

		let len=Math.ceil(figures.length/4);//向上取整
		this.imgContainer.style.height=len*140+(len-1)*15+'px';

	};




	window.$Img=Img;

})(window,document)